from database.settings import settings
from database.database import DBSessionManager
from models import TaskVideo
from typing import List, Dict, Any, Optional


class TaskVideoDAO:
    def __init__(self):
        # 获取全局配置的会话管理器配置
        self.session_config = settings.get_db_session_config(
            # 可以针对TaskVideoDAO进行特殊配置
            exclude_fields={"password", "api_key"}  # 排除敏感字段
        )
        self.batch_size = 1000  # 默认批量大小

    def create_task_videos(self, videos: List[TaskVideo], batch_size: Optional[int] = None) -> List[Dict[str, Any]]:
        """
        创建任务视频（自动序列化）

        Args:
            videos: 视频对象列表
            batch_size: 批次大小（可选）

        Returns:
            序列化后的视频列表
        """
        batch_size = batch_size or self.batch_size
        with DBSessionManager(**self.session_config) as db:
            # 使用分批次批量插入优化
            return db.batch_insert(TaskVideo, videos, batch_size)

    def create_task_videos_mappings(self, video_dicts: List[Dict[str, Any]], batch_size: Optional[int] = None) -> List[
        Dict[str, Any]]:
        """
        使用字典映射高效创建任务视频

        Args:
            video_dicts: 视频字典列表
            batch_size: 批次大小（可选）

        Returns:
            创建的视频列表（已序列化）
        """
        batch_size = batch_size or self.batch_size
        with DBSessionManager(**self.session_config) as db:
            # 使用更高效的字典映射插入
            return db.batch_insert_mappings(TaskVideo, video_dicts, batch_size)

    def update_task_videos(self, videos: List[TaskVideo]) -> int:
        """
        更新任务视频（高效批量更新）

        Args:
            videos: 要更新的视频对象列表

        Returns:
            更新的记录数
        """
        # 转换为字典列表（安全方式）
        video_dicts = [{
            'id': video.id,
            # 只包含需要更新的字段
            'title': video.title,
            'url': video.url,
            'video_path': video.video_path,
            'is_down': video.is_down,
            'type_name': video.type_name
            # 添加其他需要更新的字段...
        } for video in videos if hasattr(video, 'id') and video.id is not None]

        with DBSessionManager(**self.session_config) as db:
            # 使用高效批量更新
            return db.batch_update(TaskVideo, video_dicts)

    def update_video_path(self, video_id: int, video_path: str) -> int:
        """
        更新视频路径

        Args:
            video_id: 视频ID
            video_path: 新的视频路径

        Returns:
            更新的记录数
        """
        with DBSessionManager(**self.session_config) as db:
            # 使用高效更新方式，禁用会话同步
            result = db.query(TaskVideo).filter(TaskVideo.id == video_id).update(
                {"video_path": video_path},
                synchronize_session=False
            )
            return result

    def get_all_ids(self) -> List[int]:
        """
        获取所有视频ID（高效查询）

        Returns:
            ID列表
        """
        with DBSessionManager(**self.session_config) as db:
            # 直接查询id字段，避免加载完整对象
            return [id_ for (id_,) in db.query(TaskVideo.id).all()]

    def check_task_video_exists(self, video_id: int) -> bool:
        """
        检测视频是否存在

        Args:
            video_id: 视频ID

        Returns:
            是否存在
        """
        with DBSessionManager(**self.session_config) as db:
            return db.exists(db.query(TaskVideo.id).filter(TaskVideo.id == video_id))

    def get_all_task_videos(self) -> List[Dict[str, Any]]:
        """
        获取所有任务视频（自动序列化）

        Returns:
            序列化后的视频列表
        """
        with DBSessionManager(**self.session_config) as db:
            return db.all(db.query(TaskVideo))

    def get_all_video_path_list(self) -> List[Dict[str, Any]]:
        """
        获取未下载的视频内容

        Returns:
            未下载的视频列表
        """
        # 创建自定义会话配置，指定日期格式
        custom_config = self.session_config.copy()
        custom_config.update({
            "datetime_format": "%Y-%m-%d"  # 指定日期格式
        })
        with DBSessionManager(**custom_config) as db:
            return db.all(
                db.query(TaskVideo)
                .filter(TaskVideo.video_path.isnot(None), TaskVideo.is_down == 0)
            )

    def get_all_video_is_down_list(self) -> List[Dict[str, Any]]:
        """
        获取已下载的视频内容

        Returns:
            已下载的视频列表
        """
        with DBSessionManager(**self.session_config) as db:
            return db.all(
                db.query(TaskVideo)
                .filter(TaskVideo.is_down == 1)
            )

    def get_task_videos_paginated(self, skip: int = 0, limit: int = 100) -> List[Dict[str, Any]]:
        """
        分页获取任务视频

        Args:
            skip: 跳过数量
            limit: 限制数量

        Returns:
            分页后的视频列表
        """
        with DBSessionManager(**self.session_config) as db:
            return db.all(
                db.query(TaskVideo)
                .offset(skip)
                .limit(limit)
            )

    def delete_task_video_by_id(self, video_id: int) -> bool:
        """
        删除任务视频

        Args:
            video_id: 视频ID

        Returns:
            是否删除成功
        """
        with DBSessionManager(**self.session_config) as db:
            # 使用更安全的方式删除
            result = db.query(TaskVideo).filter(TaskVideo.id == video_id).delete(
                synchronize_session=False
            )
            db.commit()
            return result > 0

    def get_null_task_videos(self) -> List[Dict[str, Any]]:
        """
        获取视频路径为空的视频

        Returns:
            视频路径为空的视频列表
        """
        with DBSessionManager(**self.session_config) as db:
            return db.all(
                db.query(TaskVideo)
                .filter(TaskVideo.video_path.is_(None))
            )

    def get_not_null_task_videos(self) -> List[Dict[str, Any]]:
        """
        获取视频路径不为空的视频

        Returns:
            视频路径不为空的视频列表
        """
        with DBSessionManager(**self.session_config) as db:
            return db.all(
                db.query(TaskVideo)
                .filter(TaskVideo.video_path.isnot(None))
            )

    def get_ids_by_type_name(self, type_name: Optional[str] = None) -> List[int]:
        """
        获取特定类型的视频ID

        Args:
            type_name: 类型名称（可选）

        Returns:
            ID列表
        """
        with DBSessionManager(**self.session_config) as db:
            query = db.query(TaskVideo.id)
            if type_name:
                query = query.filter(TaskVideo.type_name == type_name)
            return [id_ for (id_,) in query.all()]

    def update_task_video_is_down_by_id(self, video_id: int, is_down: int) -> int:
        """
        更新视频下载状态

        Args:
            video_id: 视频ID
            is_down: 下载状态

        Returns:
            更新的记录数
        """
        with DBSessionManager(**self.session_config) as db:
            # 使用高效更新方式
            result = db.query(TaskVideo).filter(TaskVideo.id == video_id).update(
                {"is_down": is_down},
                synchronize_session=False
            )
            return result

    def process_videos_in_batches(self, process_func, filter_condition=None):
        """
        流式处理视频（避免内存问题）

        Args:
            process_func: 处理函数
            filter_condition: 过滤条件（可选）

        Returns:
            处理的记录数
        """
        with DBSessionManager(**self.session_config) as db:
            query = db.query(TaskVideo)
            if filter_condition:
                query = query.filter(filter_condition)

            return db.process_in_batches(
                query,
                process_func,
                serialize=True
            )

    def batch_update_video_paths(self, path_map: Dict[int, str]) -> int:
        """
        高效批量更新视频路径

        Args:
            path_map: {video_id: video_path} 映射

        Returns:
            更新的记录数
        """
        with DBSessionManager(**self.session_config) as db:
            return db.batch_update_by_ids(
                TaskVideo,
                "id",
                path_map,
                status_field="video_path"
            )